<template>
  <div class="case-generator">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>智能用例生成</span>
          <el-button type="primary" @click="showHistory = !showHistory">
            {{ showHistory ? '隐藏历史' : '查看历史' }}
          </el-button>
        </div>
      </template>

      <el-steps :active="currentStep" finish-status="success" align-center>
        <el-step title="上传文档" />
        <el-step title="解析配置" />
        <el-step title="生成用例" />
        <el-step title="预览确认" />
      </el-steps>

      <!-- 步骤1: 上传OpenAPI文档 -->
      <div v-show="currentStep === 0" class="step-content">
        <el-form :model="uploadForm" label-width="120px">
          <el-form-item label="选择项目">
            <el-select
              v-model="uploadForm.project_id"
              placeholder="请选择项目"
              style="width: 100%"
              filterable
            >
              <el-option
                v-for="project in projects"
                :key="project.id"
                :label="project.name"
                :value="project.id"
              />
            </el-select>
          </el-form-item>

          <el-form-item label="上传方式">
            <el-radio-group v-model="uploadForm.upload_type">
              <el-radio label="file">上传文件</el-radio>
              <el-radio label="url">URL地址</el-radio>
              <el-radio label="text">粘贴内容</el-radio>
            </el-radio-group>
          </el-form-item>

          <el-form-item v-if="uploadForm.upload_type === 'file'" label="选择文件">
            <el-upload
              :auto-upload="false"
              :on-change="handleFileChange"
              :limit="1"
              accept=".json,.yaml,.yml"
              drag
            >
              <el-icon class="el-icon--upload"><upload-filled /></el-icon>
              <div class="el-upload__text">
                将文件拖到此处，或<em>点击上传</em>
              </div>
              <template #tip>
                <div class="el-upload__tip">
                  支持 OpenAPI 3.0 格式的 JSON 或 YAML 文件
                </div>
              </template>
            </el-upload>
          </el-form-item>

          <el-form-item v-if="uploadForm.upload_type === 'url'" label="文档URL">
            <el-input
              v-model="uploadForm.url"
              placeholder="请输入OpenAPI文档的URL地址"
            />
          </el-form-item>

          <el-form-item v-if="uploadForm.upload_type === 'text'" label="文档内容">
            <el-input
              v-model="uploadForm.content"
              type="textarea"
              :rows="10"
              placeholder="请粘贴OpenAPI文档内容（JSON或YAML格式）"
            />
          </el-form-item>

          <el-form-item>
            <el-button type="primary" @click="handleUpload" :loading="uploading">
              下一步
            </el-button>
          </el-form-item>
        </el-form>
      </div>

      <!-- 步骤2: 解析配置 -->
      <div v-show="currentStep === 1" class="step-content">
        <el-form :model="parseConfig" label-width="140px">
          <el-form-item label="生成策略">
            <el-radio-group v-model="parseConfig.strategy">
              <el-radio label="all">全部接口</el-radio>
              <el-radio label="selected">选择接口</el-radio>
              <el-radio label="tag">按标签筛选</el-radio>
            </el-radio-group>
          </el-form-item>

          <el-form-item v-if="parseConfig.strategy === 'selected'" label="选择接口">
            <el-transfer
              v-model="parseConfig.selected_apis"
              :data="apiList"
              :titles="['可用接口', '已选接口']"
              filterable
            />
          </el-form-item>

          <el-form-item v-if="parseConfig.strategy === 'tag'" label="选择标签">
            <el-checkbox-group v-model="parseConfig.tags">
              <el-checkbox v-for="tag in availableTags" :key="tag" :label="tag" />
            </el-checkbox-group>
          </el-form-item>

          <el-form-item label="生成正向用例">
            <el-switch v-model="parseConfig.generate_positive" />
          </el-form-item>

          <el-form-item label="生成负向用例">
            <el-switch v-model="parseConfig.generate_negative" />
          </el-form-item>

          <el-form-item label="生成边界用例">
            <el-switch v-model="parseConfig.generate_boundary" />
          </el-form-item>

          <el-form-item label="自动添加断言">
            <el-switch v-model="parseConfig.auto_assertion" />
          </el-form-item>

          <el-form-item>
            <el-button @click="currentStep = 0">上一步</el-button>
            <el-button type="primary" @click="handleGenerate" :loading="generating">
              生成用例
            </el-button>
          </el-form-item>
        </el-form>
      </div>

      <!-- 步骤3: 生成中 -->
      <div v-show="currentStep === 2" class="step-content">
        <div class="generating-status">
          <el-icon class="is-loading" :size="50"><loading /></el-icon>
          <p>正在生成测试用例，请稍候...</p>
          <el-progress :percentage="generateProgress" />
        </div>
      </div>

      <!-- 步骤4: 预览确认 -->
      <div v-show="currentStep === 3" class="step-content">
        <el-alert
          title="用例生成完成"
          type="success"
          :description="`共生成 ${generatedCases.length} 个测试用例`"
          show-icon
          :closable="false"
        />

        <div class="case-list">
          <el-table :data="generatedCases" border style="margin-top: 20px;">
            <el-table-column type="selection" width="55" />
            <el-table-column prop="name" label="用例名称" min-width="200" />
            <el-table-column prop="method" label="方法" width="100">
              <template #default="{ row }">
                <el-tag :type="getMethodType(row.method)">{{ row.method }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="path" label="路径" min-width="200" />
            <el-table-column prop="case_type" label="类型" width="100">
              <template #default="{ row }">
                <el-tag v-if="row.case_type === 'positive'" type="success">正向</el-tag>
                <el-tag v-else-if="row.case_type === 'negative'" type="danger">负向</el-tag>
                <el-tag v-else type="warning">边界</el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="150">
              <template #default="{ row }">
                <el-button size="small" @click="viewCase(row)">查看</el-button>
                <el-button size="small" type="danger" @click="removeCase(row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>

        <div style="margin-top: 20px; text-align: center;">
          <el-button @click="resetGenerator">重新生成</el-button>
          <el-button type="primary" @click="saveCases" :loading="saving">
            保存用例
          </el-button>
        </div>
      </div>
    </el-card>

    <!-- 用例详情对话框 -->
    <el-dialog v-model="caseDetailVisible" title="用例详情" width="800px">
      <el-descriptions :column="2" border>
        <el-descriptions-item label="用例名称">{{ currentCase.name }}</el-descriptions-item>
        <el-descriptions-item label="请求方法">{{ currentCase.method }}</el-descriptions-item>
        <el-descriptions-item label="请求路径" :span="2">{{ currentCase.path }}</el-descriptions-item>
        <el-descriptions-item label="请求头" :span="2">
          <pre>{{ JSON.stringify(currentCase.headers, null, 2) }}</pre>
        </el-descriptions-item>
        <el-descriptions-item label="请求参数" :span="2">
          <pre>{{ JSON.stringify(currentCase.body, null, 2) }}</pre>
        </el-descriptions-item>
        <el-descriptions-item label="断言" :span="2">
          <pre>{{ JSON.stringify(currentCase.assertions, null, 2) }}</pre>
        </el-descriptions-item>
      </el-descriptions>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { UploadFilled, Loading } from '@element-plus/icons-vue'
import { getProjects, parseOpenAPI, generateTestCases, createTestCase } from '@/api'

const currentStep = ref(0)
const showHistory = ref(false)
const uploading = ref(false)
const generating = ref(false)
const saving = ref(false)
const generateProgress = ref(0)

const projects = ref([])
const apiList = ref([])
const availableTags = ref([])
const generatedCases = ref([])
const caseDetailVisible = ref(false)
const currentCase = ref({})

const uploadForm = reactive({
  project_id: null,
  upload_type: 'file',
  file: null,
  url: '',
  content: ''
})

const parseConfig = reactive({
  strategy: 'all',
  selected_apis: [],
  tags: [],
  generate_positive: true,
  generate_negative: true,
  generate_boundary: false,
  auto_assertion: true
})

onMounted(() => {
  loadProjects()
})

const loadProjects = async () => {
  try {
    const result = await getProjects()
    projects.value = result.data || []
  } catch (error) {
    ElMessage.error('加载项目列表失败')
  }
}

const handleFileChange = (file) => {
  uploadForm.file = file.raw
}

const handleUpload = async () => {
  if (!uploadForm.project_id) {
    ElMessage.warning('请选择项目')
    return
  }

  uploading.value = true
  try {
    let content = ''
    
    if (uploadForm.upload_type === 'file') {
      if (!uploadForm.file) {
        ElMessage.warning('请选择文件')
        return
      }
      // 读取文件内容
      content = await readFileContent(uploadForm.file)
    } else if (uploadForm.upload_type === 'url') {
      if (!uploadForm.url) {
        ElMessage.warning('请输入URL地址')
        return
      }
      content = uploadForm.url
    } else {
      if (!uploadForm.content) {
        ElMessage.warning('请粘贴文档内容')
        return
      }
      content = uploadForm.content
    }

    // 解析OpenAPI文档
    const result = await parseOpenAPI(uploadForm.project_id, {
      content,
      type: uploadForm.upload_type
    })

    if (result.success) {
      // 提取API列表和标签
      apiList.value = result.data.apis.map(api => ({
        key: api.id,
        label: `${api.method} ${api.path}`,
        ...api
      }))
      availableTags.value = result.data.tags || []
      
      ElMessage.success('文档解析成功')
      currentStep.value = 1
    }
  } catch (error) {
    ElMessage.error('文档解析失败：' + error.message)
  } finally {
    uploading.value = false
  }
}

const handleGenerate = async () => {
  generating.value = true
  currentStep.value = 2
  generateProgress.value = 0

  try {
    // 模拟进度
    const progressInterval = setInterval(() => {
      if (generateProgress.value < 90) {
        generateProgress.value += 10
      }
    }, 500)

    const result = await generateTestCases({
      project_id: uploadForm.project_id,
      strategy: parseConfig.strategy,
      selected_apis: parseConfig.selected_apis,
      tags: parseConfig.tags,
      generate_positive: parseConfig.generate_positive,
      generate_negative: parseConfig.generate_negative,
      generate_boundary: parseConfig.generate_boundary,
      auto_assertion: parseConfig.auto_assertion
    })

    clearInterval(progressInterval)
    generateProgress.value = 100

    if (result.success) {
      generatedCases.value = result.data || []
      setTimeout(() => {
        currentStep.value = 3
      }, 500)
    }
  } catch (error) {
    ElMessage.error('生成用例失败：' + error.message)
    currentStep.value = 1
  } finally {
    generating.value = false
  }
}

const saveCases = async () => {
  if (generatedCases.value.length === 0) {
    ElMessage.warning('没有可保存的用例')
    return
  }

  saving.value = true
  try {
    let successCount = 0
    for (const caseData of generatedCases.value) {
      try {
        await createTestCase(caseData)
        successCount++
      } catch (error) {
        console.error('保存用例失败:', error)
      }
    }

    ElMessage.success(`成功保存 ${successCount} 个用例`)
    resetGenerator()
  } catch (error) {
    ElMessage.error('保存用例失败')
  } finally {
    saving.value = false
  }
}

const viewCase = (caseData) => {
  currentCase.value = caseData
  caseDetailVisible.value = true
}

const removeCase = (caseData) => {
  const index = generatedCases.value.findIndex(c => c === caseData)
  if (index > -1) {
    generatedCases.value.splice(index, 1)
  }
}

const resetGenerator = () => {
  currentStep.value = 0
  generatedCases.value = []
  generateProgress.value = 0
  uploadForm.file = null
  uploadForm.url = ''
  uploadForm.content = ''
}

const getMethodType = (method) => {
  const types = {
    GET: 'success',
    POST: 'primary',
    PUT: 'warning',
    DELETE: 'danger',
    PATCH: 'info'
  }
  return types[method] || ''
}

const readFileContent = (file) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = (e) => resolve(e.target.result)
    reader.onerror = reject
    reader.readAsText(file)
  })
}
</script>

<style scoped>
.case-generator {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.step-content {
  margin-top: 30px;
  padding: 20px;
}

.generating-status {
  text-align: center;
  padding: 50px 0;
}

.generating-status p {
  margin: 20px 0;
  font-size: 16px;
  color: #606266;
}

.case-list {
  margin-top: 20px;
}

pre {
  background: #f5f7fa;
  padding: 10px;
  border-radius: 4px;
  max-height: 200px;
  overflow: auto;
}
</style>
